3 class ResourceLoaderStartUpModuleTest
extends ResourceLoaderTestCase
{
5 protected static function expandPlaceholders( $text ) {
7 '{blankVer}' => self
::BLANK_VERSION
11 public function provideGetModuleRegistrations() {
14 'msg' => 'Empty registry',
17 mw.loader.addSource( {
18 "local": "/w/load.php"
20 mw.loader.register( [] );'
23 'msg' => 'Basic registry',
25 'test.blank' => new ResourceLoaderTestModule(),
28 mw.loader.addSource( {
29 "local": "/w/load.php"
39 'msg' => 'Omit raw modules from registry',
41 'test.raw' => new ResourceLoaderTestModule( [ 'isRaw' => true ] ),
42 'test.blank' => new ResourceLoaderTestModule(),
45 mw.loader.addSource( {
46 "local": "/w/load.php"
56 'msg' => 'Version falls back gracefully if getVersionHash throws',
59 ( $mock = $this->getMockBuilder( ResourceLoaderTestModule
::class )
60 ->setMethods( [ 'getVersionHash' ] )->getMock() )
61 && $mock->method( 'getVersionHash' )->will(
62 $this->throwException( new Exception
)
67 mw.loader.addSource( {
68 "local": "/w/load.php"
81 'msg' => 'Use version from getVersionHash',
84 ( $mock = $this->getMockBuilder( ResourceLoaderTestModule
::class )
85 ->setMethods( [ 'getVersionHash' ] )->getMock() )
86 && $mock->method( 'getVersionHash' )->willReturn( '1234567' )
90 mw.loader.addSource( {
91 "local": "/w/load.php"
101 'msg' => 'Re-hash version from getVersionHash if too long',
104 ( $mock = $this->getMockBuilder( ResourceLoaderTestModule
::class )
105 ->setMethods( [ 'getVersionHash' ] )->getMock() )
106 && $mock->method( 'getVersionHash' )->willReturn( '12345678' )
110 mw.loader.addSource( {
111 "local": "/w/load.php"
113 mw.loader.register( [
121 'msg' => 'Group signature',
123 'test.blank' => new ResourceLoaderTestModule(),
124 'test.group.foo' => new ResourceLoaderTestModule( [ 'group' => 'x-foo' ] ),
125 'test.group.bar' => new ResourceLoaderTestModule( [ 'group' => 'x-bar' ] ),
128 mw.loader.addSource( {
129 "local": "/w/load.php"
131 mw.loader.register( [
151 'msg' => 'Different target (non-test should not be registered)',
153 'test.blank' => new ResourceLoaderTestModule(),
154 'test.target.foo' => new ResourceLoaderTestModule( [ 'targets' => [ 'x-foo' ] ] ),
157 mw.loader.addSource( {
158 "local": "/w/load.php"
160 mw.loader.register( [
168 'msg' => 'Safemode disabled (default; register all modules)',
170 // Default origin: ORIGIN_CORE_SITEWIDE
171 'test.blank' => new ResourceLoaderTestModule(),
172 'test.core-generated' => new ResourceLoaderTestModule( [
173 'origin' => ResourceLoaderModule
::ORIGIN_CORE_INDIVIDUAL
175 'test.sitewide' => new ResourceLoaderTestModule( [
176 'origin' => ResourceLoaderModule
::ORIGIN_USER_SITEWIDE
178 'test.user' => new ResourceLoaderTestModule( [
179 'origin' => ResourceLoaderModule
::ORIGIN_USER_INDIVIDUAL
183 mw.loader.addSource( {
184 "local": "/w/load.php"
186 mw.loader.register( [
192 "test.core-generated",
206 'msg' => 'Safemode enabled (filter modules with user/site origin)',
207 'extraQuery' => [ 'safemode' => '1' ],
209 // Default origin: ORIGIN_CORE_SITEWIDE
210 'test.blank' => new ResourceLoaderTestModule(),
211 'test.core-generated' => new ResourceLoaderTestModule( [
212 'origin' => ResourceLoaderModule
::ORIGIN_CORE_INDIVIDUAL
214 'test.sitewide' => new ResourceLoaderTestModule( [
215 'origin' => ResourceLoaderModule
::ORIGIN_USER_SITEWIDE
217 'test.user' => new ResourceLoaderTestModule( [
218 'origin' => ResourceLoaderModule
::ORIGIN_USER_INDIVIDUAL
222 mw.loader.addSource( {
223 "local": "/w/load.php"
225 mw.loader.register( [
231 "test.core-generated",
237 'msg' => 'Foreign source',
240 'loadScript' => 'http://example.org/w/load.php',
241 'apiScript' => 'http://example.org/w/api.php',
245 'test.blank' => new ResourceLoaderTestModule( [ 'source' => 'example' ] ),
248 mw.loader.addSource( {
249 "local": "/w/load.php",
250 "example": "http://example.org/w/load.php"
252 mw.loader.register( [
263 'msg' => 'Conditional dependency function',
265 'test.x.core' => new ResourceLoaderTestModule(),
266 'test.x.polyfill' => new ResourceLoaderTestModule( [
267 'skipFunction' => 'return true;'
269 'test.y.polyfill' => new ResourceLoaderTestModule( [
277 'test.z.foo' => new ResourceLoaderTestModule( [
286 mw.loader.addSource( {
287 "local": "/w/load.php"
289 mw.loader.register( [
308 "return !!( window.JSON \u0026\u0026 JSON.parse \u0026\u0026 JSON.stringify);"
322 // This may seem like an edge case, but a plain MediaWiki core install
323 // with a few extensions installed is likely far more complex than this
324 // even, not to mention an install like Wikipedia.
325 // TODO: Make this even more realistic.
326 'msg' => 'Advanced (everything combined)',
329 'loadScript' => 'http://example.org/w/load.php',
330 'apiScript' => 'http://example.org/w/api.php',
334 'test.blank' => new ResourceLoaderTestModule(),
335 'test.x.core' => new ResourceLoaderTestModule(),
336 'test.x.util' => new ResourceLoaderTestModule( [
341 'test.x.foo' => new ResourceLoaderTestModule( [
346 'test.x.bar' => new ResourceLoaderTestModule( [
352 'test.x.quux' => new ResourceLoaderTestModule( [
360 'test.group.foo.1' => new ResourceLoaderTestModule( [
363 'test.group.foo.2' => new ResourceLoaderTestModule( [
366 'test.group.bar.1' => new ResourceLoaderTestModule( [
369 'test.group.bar.2' => new ResourceLoaderTestModule( [
371 'source' => 'example',
373 'test.target.foo' => new ResourceLoaderTestModule( [
374 'targets' => [ 'x-foo' ],
376 'test.target.bar' => new ResourceLoaderTestModule( [
377 'source' => 'example',
378 'targets' => [ 'x-foo' ],
382 mw.loader.addSource( {
383 "local": "/w/load.php",
384 "example": "http://example.org/w/load.php"
386 mw.loader.register( [
456 * @dataProvider provideGetModuleRegistrations
457 * @covers ResourceLoaderStartUpModule::getModuleRegistrations
458 * @covers ResourceLoaderStartUpModule::compileUnresolvedDependencies
459 * @covers ResourceLoader::makeLoaderRegisterScript
461 public function testGetModuleRegistrations( $case ) {
462 if ( isset( $case['sources'] ) ) {
463 $this->setMwGlobals( 'wgResourceLoaderSources', $case['sources'] );
466 $extraQuery = $case['extraQuery'] ??
[];
467 $context = $this->getResourceLoaderContext( $extraQuery );
468 $rl = $context->getResourceLoader();
469 $rl->register( $case['modules'] );
470 $module = new ResourceLoaderStartUpModule();
471 $out = ltrim( $case['out'], "\n" );
473 // Disable log from getModuleRegistrations via MWExceptionHandler
474 // for case where getVersionHash() is expected to throw.
475 $this->setLogger( 'exception', new Psr\Log\
NullLogger() );
478 self
::expandPlaceholders( $out ),
479 $module->getModuleRegistrations( $context ),
484 public static function provideRegistrations() {
487 'test.blank' => new ResourceLoaderTestModule(),
488 'test.min' => new ResourceLoaderTestModule( [
503 * @covers ResourceLoaderStartUpModule::getModuleRegistrations
504 * @dataProvider provideRegistrations
506 public function testRegistrationsMinified( $modules ) {
507 $this->setMwGlobals( 'wgResourceLoaderDebug', false );
509 $context = $this->getResourceLoaderContext();
510 $rl = $context->getResourceLoader();
511 $rl->register( $modules );
512 $module = new ResourceLoaderStartUpModule();
513 $out = 'mw.loader.addSource({"local":"/w/load.php"});' . "\n"
514 . 'mw.loader.register(['
515 . '["test.blank","{blankVer}"],'
516 . '["test.min","{blankVer}",[0],null,null,'
517 . '"return!!(window.JSON\u0026\u0026JSON.parse\u0026\u0026JSON.stringify);"'
521 self
::expandPlaceholders( $out ),
522 $module->getModuleRegistrations( $context ),
528 * @covers ResourceLoaderStartUpModule::getModuleRegistrations
529 * @dataProvider provideRegistrations
531 public function testRegistrationsUnminified( $modules ) {
532 $context = $this->getResourceLoaderContext();
533 $rl = $context->getResourceLoader();
534 $rl->register( $modules );
535 $module = new ResourceLoaderStartUpModule();
537 'mw.loader.addSource( {
538 "local": "/w/load.php"
540 mw.loader.register( [
553 "return !!( window.JSON \u0026\u0026 JSON.parse \u0026\u0026 JSON.stringify);"
558 self
::expandPlaceholders( $out ),
559 $module->getModuleRegistrations( $context ),
565 * @covers ResourceLoaderStartupModule::getDefinitionSummary
567 public function testGetVersionHash_varyConfig() {
568 $context = $this->getResourceLoaderContext();
570 $this->setMwGlobals( 'wgArticlePath', '/w1' );
571 $module = new ResourceLoaderStartupModule();
572 $version1 = $module->getVersionHash( $context );
573 $module = new ResourceLoaderStartupModule();
574 $version2 = $module->getVersionHash( $context );
576 $this->setMwGlobals( 'wgArticlePath', '/w3' );
577 $module = new ResourceLoaderStartupModule();
578 $version3 = $module->getVersionHash( $context );
583 'Deterministic version hash'
586 $this->assertNotEquals(
589 'Config change impacts version hash'
594 * @covers ResourceLoaderStartupModule
596 public function testGetVersionHash_varyModule() {
597 $context1 = $this->getResourceLoaderContext();
598 $rl1 = $context1->getResourceLoader();
600 'test.a' => new ResourceLoaderTestModule(),
601 'test.b' => new ResourceLoaderTestModule(),
603 $module = new ResourceLoaderStartupModule();
604 $version1 = $module->getVersionHash( $context1 );
606 $context2 = $this->getResourceLoaderContext();
607 $rl2 = $context2->getResourceLoader();
609 'test.b' => new ResourceLoaderTestModule(),
610 'test.c' => new ResourceLoaderTestModule(),
612 $module = new ResourceLoaderStartupModule();
613 $version2 = $module->getVersionHash( $context2 );
615 $context3 = $this->getResourceLoaderContext();
616 $rl3 = $context3->getResourceLoader();
618 'test.a' => new ResourceLoaderTestModule(),
619 'test.b' => new ResourceLoaderTestModule( [ 'script' => 'different' ] ),
621 $module = new ResourceLoaderStartupModule();
622 $version3 = $module->getVersionHash( $context3 );
624 // Module name *is* significant (T201686)
625 $this->assertNotEquals(
628 'Module name is significant'
631 $this->assertNotEquals(
634 'Hash change of any module impacts startup hash'
639 * @covers ResourceLoaderStartupModule
641 public function testGetVersionHash_varyDeps() {
642 $context = $this->getResourceLoaderContext();
643 $rl = $context->getResourceLoader();
645 'test.a' => new ResourceLoaderTestModule( [ 'dependencies' => [ 'x', 'y' ] ] ),
647 $module = new ResourceLoaderStartupModule();
648 $version1 = $module->getVersionHash( $context );
650 $context = $this->getResourceLoaderContext();
651 $rl = $context->getResourceLoader();
653 'test.a' => new ResourceLoaderTestModule( [ 'dependencies' => [ 'x', 'z' ] ] ),
655 $module = new ResourceLoaderStartupModule();
656 $version2 = $module->getVersionHash( $context );
658 // Dependencies *are* significant (T201686)
659 $this->assertNotEquals(
662 'Dependencies are significant'